home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume89
/
comm
/
vt100r29.4
< prev
next >
Wrap
Internet Message Format
|
1989-10-20
|
41KB
Path: xanth!mcnc!rutgers!ucsd!tut.cis.ohio-state.edu!mailrus!ames!sun-barr!newstop!sun!swap!page
From: page%swap@Sun.COM (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v89i181: vt100 - terminal emulator v2.9, Part04/09
Message-ID: <126579@sun.Eng.Sun.COM>
Date: 20 Oct 89 06:10:10 GMT
Sender: news@sun.Eng.Sun.COM
Lines: 1821
Approved: page@sun.com
Submitted-by: acs@pccuts.pcc.amdahl.com (Tony Sumrall)
Posting-number: Volume 89, Issue 181
Archive-name: comm/vt100r29.4
# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
# Zmodem/rz.c
# This is archive 4 of a 9-part kit.
# This archive created: Thu Oct 19 22:30:30 1989
if `test ! -d Zmodem`
then
mkdir Zmodem
echo "mkdir Zmodem"
fi
echo "extracting Zmodem/rz.c"
sed 's/^X//' << \SHAR_EOF > Zmodem/rz.c
X#define VERSION "1.26 08-21-87"
X#define PUBDIR "/usr/spool/uucppublic"
X
X/*% cc -M0 -Ox -K -i % -o rz; size rz;
X<-xtx-*> cc386 -Ox rz.c -o $B/rz; size $B/rz
X *
X * rz.c By Chuck Forsberg
X *
X * cc -O rz.c -o rz USG (3.0) Unix
X * cc -O -DV7 rz.c -o rz Unix V7, BSD 2.8 - 4.3
X *
X * ln rz rb; ln rz rx For either system
X *
X * ln rz /usr/bin/rzrmail For remote mail. Make this the
X * login shell. rzrmail then calls
X * rmail(1) to deliver mail.
X *
X *
X * Amiga version by Frank Harper using Aztec C 3.4b
X *
X * cc +L rz.c;cc +L SerIO.c;cc +L term.c;ln rz.o SerIO.o term.o -lc32
X * or just use the makefile
X *
X * See Amiga.doc for more details on Amiga version
X *
X * Unix is a trademark of Western Electric Company
X *
X * A program for Unix to receive files and commands from computers running
X * Professional-YAM, PowerCom, YAM, IMP, or programs supporting XMODEM.
X * rz uses Unix buffered input to reduce wasted CPU time.
X *
X * Iff the program is invoked by rzCOMMAND, output is piped to
X * "COMMAND filename"
X *
X * Some systems (Venix, Coherent, Regulus) may not support tty raw mode
X * read(2) the same way as Unix. ONEREAD must be defined to force one
X * character reads for these systems. Added 7-01-84 CAF
X *
X * Alarm signal handling changed to work with 4.2 BSD 7-15-84 CAF
X *
X * BIX added 6-30-87 to support BIX(TM) upload protocol used by the
X * Byte Information Exchange.
X *
X * NFGVMIN Updated 2-18-87 CAF for Xenix systems where c_cc[VMIN]
X * doesn't work properly (even though it compiles without error!),
X *
X * HOWMANY may be tuned for best performance
X *
X * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin
X */
X#ifdef AMIGA
X#define LOGFILE "rzlog"
X#include <time.h>
X#include <stdio.h>
X#include <ctype.h>
X#include <stat.h>
X#include <devices/timer.h>
X#include <devices/serial.h>
X#include <libraries/dos.h>
X#include "intuition/intuition.h"
X#include <exec/memory.h>
X
X#define RZ
X
Xvoid *OpenLibrary();
Xstruct Window *OpenWindow();
X
Xstruct IntuitionBase *IntuitionBase;
Xstruct NewWindow nw = {
X 0, 0, /* start position */
X 640, 120, /* width, height */
X -1, -1, /* detail pen, block pen */
X CLOSEWINDOW, /* IDCMP flags */
X ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING | WINDOWCLOSE
X | NOCAREREFRESH, /* window flags */
X NULL, /* pointer to first user gadget */
X NULL, /* pointer to user checkmark */
X (UBYTE *)"Rz", /* window title */
X NULL, /* pointer to screen (later) */
X NULL, /* pointer to superbitmap */
X 50,40,-1,-1, /* sizing limits min and max */
X WBENCHSCREEN /* type of screen in which to open */
X };
Xint InitSer = FALSE;
Xint gmt_diff_set=FALSE; /* Has GMT offset been set? */
Xint gmt_diff; /* Local offset from GMT time */
Xint SetProtect=TRUE;
Xint Term=FALSE; /* Use Terminal mode ? */
Xint WaitC=TRUE; /* Wait for confirmation before closing window?*/
Xstruct IOStdReq *ConWriteReq, *ConReadReq;
Xstruct Window *Win;
Xstruct MsgPort *ConReadPort,*ConWritePort;
Xint WinOutPut;
Xint FullDuplex=TRUE;
Xstruct IOExtSer *InSer, *OutSer;
Xstruct MsgPort *InSerPort, *OutSerPort;
XULONG InSerSigMask, OutSerSigMask;
XUBYTE SerOpen;
Xstruct timerequest *IOTime;
Xstruct MsgPort *TimerPort;
XULONG IOTimeSigMask;
X
Xint Skip=TRUE; /* Skip files which are to big to fit on disk */
X#else
X#define LOGFILE "/tmp/rzlog"
X
X#include <stdio.h>
X#include <signal.h>
X#include <setjmp.h>
X#include <ctype.h>
XFILE *popen();
X#endif
X
X#define OK 0
X
X#ifndef AMIGA /* Already defined in <exec/types.h> */
X#define FALSE 0
X#define TRUE 1
X#endif
X
X#define ERROR (-1)
X
X/*
X * Max value for HOWMANY is 255.
X * A larger value reduces system overhead but may evoke kernel bugs.
X * 133 corresponds to an XMODEM/CRC sector
X *
X * This isn't used in Amiga version
X */
X#ifndef HOWMANY
X#define HOWMANY 133
X#endif
X
Xint Zmodem=0; /* ZMODEM protocol requested */
Xint Nozmodem = 0; /* If invoked as "rb" */
Xunsigned Baudrate;
X
Xchar *substr();
XFILE *fout;
X
X/* Ward Christensen / CP/M parameters - Don't change these! */
X#define ENQ 005
X#define CAN ('X'&037)
X#define XOFF ('s'&037)
X#define XON ('q'&037)
X#define SOH 1
X#define STX 2
X#define EOT 4
X#define ACK 6
X#define NAK 025
X#define CPMEOF 032
X#define WANTCRC 0103 /* send C not NAK to get crc not checksum */
X#define TIMEOUT (-2)
X#define RCDO (-3)
X#define ERRORMAX 5
X#define RETRYMAX 5
X#define WCEOT (-10)
X#define SECSIZ 128 /* cp/m's Magic Number record size */
X#define PATHLEN 257 /* ready for 4.2 bsd ? */
X#define KSIZE 1024 /* record size with k option */
X#define UNIXFILE 0x8000 /* happens to the the S_IFREG file mask bit for stat */
X
Xint Lastrx;
Xint Crcflg;
Xint Firstsec;
Xint Eofseen; /* indicates cpm eof (^Z) has been received */
Xint errors;
Xint Restricted=0; /* restricted; no /.. or ../ in filenames */
X#ifdef ONEREAD
X/* Sorry, Regulus and some others don't work right in raw mode! */
Xint Readnum = 1; /* Number of bytes to ask for in read() from modem */
X#else
Xint Readnum = HOWMANY; /* Number of bytes to ask for in read() from modem */
X#endif
X
X#define DEFBYTL 2000000000L /* default rx file size */
Xlong Bytesleft; /* number of bytes of incoming file left */
Xlong Modtime; /* Unix style mod time for incoming file */
X#ifndef AMIGA
Xshort Filemode; /* Unix style mode for incoming file */
X#else
Xint Filemode; /* This avoids a problem with the sscanf used to
X read Filemode */
X#endif
Xchar Pathname[PATHLEN];
Xchar *Progname; /* the name by which we were called */
X
Xint Batch=0;
Xint Wcsmask=0377;
Xint Topipe=0;
Xint MakeLCPathname=TRUE; /* make received pathname lower case */
Xint Verbose=0;
Xint Quiet=0; /* overrides logic that would otherwise set verbose */
Xint Nflag = 0; /* Don't really transfer files */
Xint Rxbinary=FALSE; /* receive all files in bin mode */
Xint Rxascii=FALSE; /* receive files in ascii (translate) mode */
Xint Thisbinary; /* current file is to be received in bin mode */
Xint Blklen; /* record length of received packets */
Xchar secbuf[KSIZE+1];
Xchar linbuf[HOWMANY];
Xint Lleft=0; /* number of characters in linbuf */
Xtime_t timep[2];
Xchar Lzmanag; /* Local file management request */
Xchar zconv; /* ZMODEM file conversion request */
Xchar zmanag; /* ZMODEM file management request */
Xchar ztrans; /* ZMODEM file transport request */
Xint Zctlesc; /* Encode control characters */
Xint Zrwindow = 1400; /* RX window size (controls garbage count) */
X
X#ifndef AMIGA
Xjmp_buf tohere; /* For the interrupt on RX timeout */
X#endif
X
X#include "rbsb.c" /* most of the system dependent stuff here */
X#include "zm.c"
X
Xint tryzhdrtype=ZRINIT; /* Header type to send corresponding to Last rx close */
X
X#ifndef AMIGA
X/*
X * Routine to calculate the free bytes on the current file system
X * ~0 means many free bytes (unknown)
X */
Xlong getfree()
X{
X return(~0L); /* many free bytes ... */
X}
X#else
Xstruct DPTR { /* Format of directory fetch pointer */
X struct FileLock *lock; /* lock on directory */
X struct FileInfoBlock *fib; /* mod'd fib for entry */
X};
X
Xstruct DPTR *dopen();
Xstruct FileLock *Lock();
Xstruct FileLock *ParentDir();
Xstruct MsgPort *DeviceProc();
Xvoid *AllocMem();
Xvoid *malloc();
X
X /*
X * Calculate free bytes on current file system
X * ~0L means number of free bytes unknown
X * Adapted from shell 2.07's devinfo routine (Thanks Matt & Steve)
X */
X
Xlong getfree()
X{
X struct DPTR *dp;
X struct InfoData *info;
X int stat;
X long retc;
X
X if ((dp = dopen ("", &stat))!=NULL) {
X info = (struct InfoData *)AllocMem((long)sizeof(struct InfoData), MEMF_PUBLIC);
X if (Info (dp->lock, info))
X retc=(info->id_NumBlocks - info->id_NumBlocksUsed)*512; /* assume 512 byte blocks */
X else {
X if(Verbose) fprintf(stderr,"getfree failed\n");
X retc=~0L;
X }
X }
X FreeMem (info,(long) sizeof(*info));
X dclose(dp);
X if(Verbose) fprintf(stderr,"%ld bytes free on disk\n",retc);
X return(retc);
X}
X
X /*
X * Change a files date
X * Lifted from Shell 2.07
X *
X */
X
Xfile_date(date,name)
Xstruct DateStamp *date;
Xchar *name;
X{
X UBYTE *ptr;
X struct MsgPort *task;
X struct FileLock *dirlock;
X struct DPTR *tmp;
X int stat;
X long ret, dos_packet();
X
X if (!(task = (struct MsgPort *)DeviceProc(name)))
X return(1);
X if (tmp = dopen(name, &stat)) {
X dirlock = (struct FileLock *)ParentDir(tmp->lock);
X ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC);
X strcpy((ptr + 1),tmp->fib->fib_FileName);
X *ptr = strlen(tmp->fib->fib_FileName);
X dclose(tmp);
X ret = dos_packet(task,34L,NULL,dirlock,
X (ULONG)&ptr[0] >> 2L,date);
X FreeMem(ptr,64L);
X UnLock(dirlock);
X }
X}
X
X/*
X * These routines come directly from shell 2.07 by Matt Dillon,
X * Manx version by Steve Drew.
X *
X * Disk directory routines
X *
X * dptr = dopen(name, stat)
X * struct DPTR *dptr;
X * char *name;
X * int *stat;
X *
X * dclose(dptr) -may be called with NULL without harm
X *
X * dopen() returns a struct DPTR, or NULL if the given file does not
X * exist. stat will be set to 1 if the file is a directory. If the
X * name is "", then the current directory is opened.
X *
X * dclose() closes a directory channel.
X *
X */
X
Xstruct DPTR *dopen(name, stat)
Xchar *name;
Xint *stat;
X{
X struct DPTR *dp;
X int i;
X
X *stat = 0;
X dp = (struct DPTR *)malloc(sizeof(struct DPTR));
X dp->lock = (struct FileLock *)Lock (name, ACCESS_READ);
X if (dp->lock == NULL) {
X free (dp);
X if(Verbose) fprintf(stderr,"Couldn't lock dir\n");
X return (NULL);
X }
X dp->fib = (struct FileInfoBlock *)
X AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
X if (!Examine (dp->lock, dp->fib)) {
X if(Verbose) fprintf(stderr,"dopen: Can't open current dir\n");
X dclose (dp);
X return (NULL);
X }
X if (dp->fib->fib_DirEntryType >= 0)
X *stat = 1;
X return (dp);
X}
X
Xdclose(dp)
Xstruct DPTR *dp;
X{
X if (dp == NULL)
X return (1);
X if (dp->fib)
X FreeMem (dp->fib,(long)sizeof(*dp->fib));
X if (dp->lock)
X UnLock (dp->lock);
X free (dp);
X return (1);
X}
Xbibi(n)
X{
X if (Zmodem)
X zmputs(Attn);
X flushmo();
X canit(); mode(0);
X if(fout) fclose(fout);
X CleanUp();
X exit(128+n);
X}
X
XWaitbibi(n)
Xint n;
X{
X ConPutChar(ConWriteReq,7);
X ConPutStr(ConWriteReq,"\nsz: Transfer aborted");
X if( WaitC ) WaitClose();
X bibi(n);
X}
X
XWaitClose()
X{
X ULONG IntuiMask;
X
X IntuiMask = 1 << (Win->UserPort->mp_SigBit);
X while(!CheckQuit()) Wait(IntuiMask);
X}
X
XAmigaInit()
X{
X IntuitionBase = (struct IntuitionBase *)
X OpenLibrary("intuition.library", 33L);
X if (IntuitionBase == NULL) {
X puts("Unable to open 1.2 or higher intuition.library");
X exit(1);
X }
X Win = OpenWindow(&nw);
X if ( Win == NULL ) {
X puts("Unable to open window");
X CleanUp();
X exit(1);
X }
X WinOutPut=TRUE;
X if( OpenConsole(&ConWriteReq,&ConReadReq,Win)) {
X puts("Couldn't open console");
X CleanUp();
X exit(1);
X }
X}
X
XCleanUp()
X{
X CloseConsole(ConReadReq,ConWriteReq);
X if( Win ) CloseWindow(Win);
X if(IntuitionBase) CloseLibrary(IntuitionBase);
X}
X
X /*
X * Send output to window
X *
X */
Xfprintf(f,s,a1,a2,a3,a4)
XFILE *f;
Xchar *s;
Xchar *a1,*a2,*a3,*a4;
X{
X char buf[256];
X
X sprintf(buf,s,a1,a2,a3,a4);
X if( WinOutPut ) ConPutStr(ConWriteReq,buf);
X else fputs(buf,f);
X}
X#endif
X
X#ifndef AMIGA
Xalrm()
X{
X longjmp(tohere, -1);
X}
X/* called by signal interrupt or terminate to clean things up */
Xbibi(n)
X{
X if (Zmodem)
X zmputs(Attn);
X canit(); mode(0);
X fprintf(stderr, "rz: caught signal %d; exiting", n);
X exit(128+n);
X}
X#endif
X
Xmain(argc, argv)
Xchar *argv[];
X{
X register char *cp;
X register npats;
X char *virgin, **patts;
X char *getenv();
X int exitcode = 0;
X
X Rxtimeout = 100;
X#ifndef AMIGA
X setbuf(stderr, NULL);
X if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh")))
X Restricted=TRUE;
X#endif
X
X chkinvok(virgin=argv[0]); /* if called as [-]rzCOMMAND set flag */
X npats = 0;
X#ifdef AMIGA
X AmigaInit();
X#endif
X while (--argc) {
X cp = *++argv;
X if (*cp == '-') {
X while( *++cp) {
X switch(*cp) {
X case '+':
X Lzmanag = ZMAPND; break;
X#ifndef AMIGA
X case '1':
X iofd = 1; break;
X#else
X case 'I':
X InitSer = TRUE; break;
X case 'B':
X Nozmodem = TRUE; break;
X#endif
X case '7':
X Wcsmask = 0177;
X case 'a':
X Rxascii=TRUE; break;
X case 'b':
X Rxbinary=TRUE; break;
X case 'c':
X Crcflg=TRUE; break;
X case 'D':
X Nflag = TRUE; break;
X case 'e':
X Zctlesc = 1; break;
X#ifdef AMIGA
X case 'h':
X FullDuplex = FALSE; break;
X case 'm':
X SetProtect = FALSE; break;
X case 'n':
X Skip = FALSE; break;
X#endif
X case 'p':
X Lzmanag = ZMPROT; break;
X case 'q':
X Quiet=TRUE; Verbose=0; break;
X#ifdef AMIGA
X case 'Q':
X WaitC = FALSE; break;
X#endif
X case 't':
X if (--argc < 1) {
X usage();
X }
X Rxtimeout = atoi(*++argv);
X if (Rxtimeout<10 || Rxtimeout>1000)
X usage();
X break;
X#ifdef AMIGA
X case 'T':
X Term=TRUE; break;
X#endif
X case 'w':
X if (--argc < 1) {
X usage();
X }
X Zrwindow = atoi(*++argv);
X break;
X case 'u':
X MakeLCPathname=FALSE; break;
X case 'v':
X ++Verbose; break;
X default:
X usage();
X }
X }
X }
X else if ( !npats && argc>0) {
X if (argv[0][0]) {
X npats=argc;
X patts=argv;
X }
X }
X }
X if (npats > 1)
X usage();
X#ifdef AMIGA
X if( mode(1)==ERROR) {
X fprintf(stderr,"Couldn't initialize serial port\n");
X Waitbibi(1);
X }
X if (Term) {
X fprintf(stderr,"Entering terminal mode, click on close box when ready to start file transfer\n");
X term();
X }
X#endif
X if (Verbose) {
X if (freopen(LOGFILE, "a", stderr)==NULL) {
X printf("Can't open log file %s\n",LOGFILE);
X exit(0200);
X }
X setbuf(stderr, NULL);
X#ifdef AMIGA
X WinOutPut=FALSE;
X#endif
X fprintf(stderr, "argv[0]=%s Progname=%s\n", virgin, Progname);
X }
X if (fromcu() && !Quiet) {
X if (Verbose == 0)
X Verbose = 2;
X }
X#ifndef AMIGA
X mode(1);
X if (signal(SIGINT, bibi) == SIG_IGN) {
X signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
X }
X else {
X signal(SIGINT, bibi); signal(SIGKILL, bibi);
X }
X signal(SIGTERM, bibi);
X#endif
X if (wcreceive(npats, patts)==ERROR) {
X exitcode=0200;
X canit();
X#ifdef AMIGA
X fprintf(stderr,"\n\007File transfer failed\n");
X#endif
X }
X#ifdef AMIGA
X else fprintf(stderr,"\nFile transfer succesful\n");
X if (Term) {
X fprintf(stderr,"Re-entering terminal mode. Click on close box to exit Rz.\n");
X term();
X }
X else if( WaitC ) {
X fprintf(stderr,"Click on close box to exit Rz\n");
X WaitClose();
X }
X CleanUp();
X#endif
X mode(0);
X if (exitcode && !Zmodem) /* bellow again with all thy might. */
X canit();
X exit(exitcode);
X}
X
X#ifdef AMIGA
Xchar *babble[] = {
X "Usage: rz [-BIYabehmnv] (ZMODEM Batch)",
X "or rb [-Iabhv] (YMODEM Batch)",
X "or rz [-Iabchv] file (XMODEM or XMODEM-1k)",
X " -I Initialize serial port, using zmodem.init file",
X " -B Force Ymodem Batch transfer",
X " -a ASCII transfer (strip CR)",
X " -b Binary transfer for all files",
X " -c Use 16 bit CRC (XMODEM)",
X " -e Ignore control characters (ZMODEM)",
X " -h Half duplex mode (only for Terminal mode)",
X " -m Don't set file modes",
X " -n No skipping over files even if to large for disk",
X " -Q Quit without waiting for click in close box",
X " -T enter Terminal mode before transferring",
X " -v Verbose more v's give more info",
X ""
X};
X
Xusage()
X{
X char **pp;
X int i,n,rows,cols,height;
X struct Screen Scr;
X char rep[20];
X
X /* Expand window, to show as many lines at once as possible */
X MoveWindow(Win,-Win->LeftEdge,-Win->TopEdge);
X if( !GetScreenData(&Scr,sizeof(struct Screen),WBENCHSCREEN)) {
X fprintf(stderr,"Couldn't get screen size");
X CleanUp();
X exit(1);
X }
X rows=Scr.Height;
X cols=Scr.Width;
X SizeWindow(Win,cols>640?640-Win->Width:cols-Win->Width,
X rows-Win->Height);
X Delay(15); /* Wait until window is resized */
X ConPutStr(ConWriteReq,"\2330 q"); /* get window bounds */
X n = 0;
X while((rep[n] = ConGetC(ConReadReq)) != 'r' && n++ < 20)
X ;
X height=0;
X i=5;
X while(rep[i]>='0' && rep[i]<='9' && i<n) {
X height*=10;
X height+=rep[i++]-'0';
X }
X for (pp=babble,i=1; **pp; ++pp,i++) {
X fprintf(stderr, "%s\n", *pp);
X if((i%height)==(height-1)) {
X WaitKey();
X ConPutStr(ConWriteReq,"\2331\0731\110\233\112"); /* Erase screen */
X }
X }
X fprintf(stderr,"%s by Chuck Forsberg, amiga version 1.0 by Frank Harper\n",VERSION);
X WaitKey();
X bibi(1);
X}
X
XWaitKey()
X{
X char ConChar;
X ULONG mask,IntuiMask,ConInMask;
X
X IntuiMask = 1 << (Win->UserPort->mp_SigBit);
X ConInMask = 1 << (ConReadPort->mp_SigBit);
X ConPutStr(ConWriteReq,"\23307\155 Press a key \23300\155");
X QueueRead(ConReadReq,&ConChar);
X mask=Wait(ConInMask|IntuiMask);
X puts("Got something");
X if(CheckQuit()) { /* Hit close box? */
X KillIO(ConReadReq);
X bibi(1);
X }
X GetMsg(ConReadPort);
X}
X#else
Xusage()
X{
X fprintf(stderr,"%s %s for %s by Chuck Forsberg\n",
X Progname, VERSION, OS);
X fprintf(stderr,"Usage: rz [-1abeuv] (ZMODEM Batch)\n");
X fprintf(stderr,"or rb [-1abuv] (YMODEM Batch)\n");
X fprintf(stderr,"or rx [-1abcv] file (XMODEM or XMODEM-1k)\n");
X fprintf(stderr," -1 For cu(1): Use fd 1 for input\n");
X fprintf(stderr," -a ASCII transfer (strip CR)\n");
X fprintf(stderr," -b Binary transfer for all files\n");
X fprintf(stderr," -c Use 16 bit CRC (XMODEM)\n");
X fprintf(stderr," -e Ignore control characters (ZMODEM)\n");
X fprintf(stderr," -v Verbose more v's give more info\n");
X exit(1);
X}
X#endif
X/*
X * Debugging information output interface routine
X */
X/* VARARGS1 */
Xvfile(f, a, b, c)
Xregister char *f;
X{
X if (Verbose > 2) {
X fprintf(stderr, f, a, b, c);
X fprintf(stderr, "\n");
X }
X}
X
X/*
X * Let's receive something already.
X */
X
Xchar *rbmsg =
X"%s ready. To begin transfer, type \"%s file ...\" to your modem program\r\n";
X
Xwcreceive(argc, argp)
Xchar **argp;
X{
X register c;
X
X if (Batch || argc==0) {
X Crcflg=(Wcsmask==0377);
X if ( !Quiet)
X fprintf(stderr, rbmsg, Progname, Nozmodem?"sb":"sz");
X if (c=tryz()) {
X if (c == ZCOMPL)
X return OK;
X if (c == ERROR)
X goto fubar;
X c = rzfiles();
X if (c)
X goto fubar;
X } else {
X for (;;) {
X if (wcrxpn(secbuf)== ERROR)
X goto fubar;
X if (secbuf[0]==0)
X return OK;
X if (procheader(secbuf) == ERROR)
X goto fubar;
X if (wcrx()==ERROR)
X goto fubar;
X }
X }
X } else {
X Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
X
X procheader(""); strcpy(Pathname, *argp);
X#ifndef AMIGA
X checkpath(Pathname);
X#endif
X fprintf(stderr, "\nrz: ready to receive %s\r\n", Pathname);
X if ((fout=fopen(Pathname, "w")) == NULL)
X return ERROR;
X if (wcrx()==ERROR)
X goto fubar;
X }
X return OK;
Xfubar:
X canit();
X#ifndef AMIGA
X if (Topipe && fout) {
X pclose(fout); return ERROR;
X }
X#endif
X if (fout)
X fclose(fout);
X if (Restricted) {
X unlink(Pathname);
X fprintf(stderr, "\r\nrz: %s removed.\r\n", Pathname);
X }
X return ERROR;
X}
X
X
X/*
X * Fetch a pathname from the other end as a C ctyle ASCIZ string.
X * Length is indeterminate as long as less than Blklen
X * A null string represents no more files (YMODEM)
X */
Xwcrxpn(rpn)
Xchar *rpn; /* receive a pathname */
X{
X register c;
X
X#ifdef NFGVMIN
X readline(1);
X#else
X purgeline();
X#endif
X
Xet_tu:
X Firstsec=TRUE; Eofseen=FALSE;
X sendline(Crcflg?WANTCRC:NAK);
X Lleft=0; /* Do read next time ... */
X while ((c = wcgetsec(rpn, 100)) != 0) {
X if (c == WCEOT) {
X zperr( "Pathname fetch returned %d", c);
X sendline(ACK);
X Lleft=0; /* Do read next time ... */
X readline(1);
X goto et_tu;
X }
X return ERROR;
X }
X sendline(ACK);
X return OK;
X}
X
X/*
X * Adapted from CMODEM13.C, written by
X * Jack M. Wierda and Roderick W. Hart
X */
X
Xwcrx()
X{
X register int sectnum, sectcurr;
X register char sendchar;
X register char *p;
X int cblklen; /* bytes to dump this block */
X
X Firstsec=TRUE;sectnum=0; Eofseen=FALSE;
X sendchar=Crcflg?WANTCRC:NAK;
X
X for (;;) {
X sendline(sendchar); /* send it now, we're ready! */
X Lleft=0; /* Do read next time ... */
X sectcurr=wcgetsec(secbuf, (sectnum&0177)?50:130);
X report(sectcurr);
X if (sectcurr==(sectnum+1 &Wcsmask)) {
X sectnum++;
X cblklen = Bytesleft>Blklen ? Blklen:Bytesleft;
X if (putsec(secbuf, cblklen)==ERROR)
X return ERROR;
X if ((Bytesleft-=cblklen) < 0)
X Bytesleft = 0;
X sendchar=ACK;
X }
X else if (sectcurr==(sectnum&Wcsmask)) {
X zperr( "Received dup Sector");
X sendchar=ACK;
X }
X else if (sectcurr==WCEOT) {
X if (closeit())
X return ERROR;
X sendline(ACK);
X Lleft=0; /* Do read next time ... */
X return OK;
X }
X else if (sectcurr==ERROR)
X return ERROR;
X else {
X zperr( "Sync Error");
X return ERROR;
X }
X }
X}
X
X/*
X * Wcgetsec fetches a Ward Christensen type sector.
X * Returns sector number encountered or ERROR if valid sector not received,
X * or CAN CAN received
X * or WCEOT if eot sector
X * time is timeout for first char, set to 4 seconds thereafter
X ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK **************
X * (Caller must do that when he is good and ready to get next sector)
X */
X
Xwcgetsec(rxbuf, maxtime)
Xchar *rxbuf;
Xint maxtime;
X{
X register checksum, wcj, firstch;
X register unsigned short oldcrc;
X register char *p;
X int sectcurr;
X
X for (Lastrx=errors=0; errors<RETRYMAX; errors++) {
X
X if ((firstch=readline(maxtime))==STX) {
X Blklen=KSIZE; goto get2;
X }
X if (firstch==SOH) {
X Blklen=SECSIZ;
Xget2:
X sectcurr=readline(1);
X if ((sectcurr+(oldcrc=readline(1)))==Wcsmask) {
X oldcrc=checksum=0;
X for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {
X if ((firstch=readline(1)) < 0)
X goto bilge;
X oldcrc=updcrc(firstch, oldcrc);
X checksum += (*p++ = firstch);
X }
X if ((firstch=readline(1)) < 0)
X goto bilge;
X if (Crcflg) {
X oldcrc=updcrc(firstch, oldcrc);
X if ((firstch=readline(1)) < 0)
X goto bilge;
X oldcrc=updcrc(firstch, oldcrc);
X if (oldcrc & 0xFFFF)
X zperr( "CRC");
X else {
X Firstsec=FALSE;
X return sectcurr;
X }
X }
X else if (((checksum-firstch)&Wcsmask)==0) {
X Firstsec=FALSE;
X return sectcurr;
X }
X else
X zperr( "Checksum");
X }
X else
X zperr("Sector number garbled");
X }
X /* make sure eot really is eot and not just mixmash */
X#ifdef NFGVMIN
X else if (firstch==EOT && readline(1)==TIMEOUT)
X return WCEOT;
X#else
X else if (firstch==EOT && Lleft==0)
X return WCEOT;
X#endif
X else if (firstch==CAN) {
X if (Lastrx==CAN) {
X zperr( "Sender CANcelled");
X return ERROR;
X } else {
X Lastrx=CAN;
X continue;
X }
X }
X else if (firstch==TIMEOUT) {
X if (Firstsec)
X goto humbug;
Xbilge:
X zperr( "TIMEOUT");
X }
X else
X zperr( "Got 0%o sector header", firstch);
X
Xhumbug:
X Lastrx=0;
X while(readline(1)!=TIMEOUT)
X ;
X if (Firstsec) {
X sendline(Crcflg?WANTCRC:NAK);
X Lleft=0; /* Do read next time ... */
X } else {
X maxtime=40; sendline(NAK);
X Lleft=0; /* Do read next time ... */
X }
X }
X /* try to stop the bubble machine. */
X canit();
X return ERROR;
X}
X#ifndef AMIGA
X/*
X * This version of readline is reasoably well suited for
X * reading many characters.
X * (except, currently, for the Regulus version!)
X *
X * timeout is in tenths of seconds
X */
Xreadline(timeout)
Xint timeout;
X{
X register n;
X static char *cdq; /* pointer for removing chars from linbuf */
X
X if (--Lleft >= 0) {
X if (Verbose > 8) {
X fprintf(stderr, "%02x ", *cdq&0377);
X }
X return (*cdq++ & Wcsmask);
X }
X n = timeout/10;
X if (n < 2)
X n = 3;
X if (Verbose > 5)
X fprintf(stderr, "Calling read: alarm=%d Readnum=%d ",
X n, Readnum);
X if (setjmp(tohere)) {
X#ifdef TIOCFLUSH
X/* ioctl(iofd, TIOCFLUSH, 0); */
X#endif
X Lleft = 0;
X if (Verbose>1)
X fprintf(stderr, "Readline:TIMEOUT\n");
X return TIMEOUT;
X }
X signal(SIGALRM, alrm); alarm(n);
X Lleft=read(iofd, cdq=linbuf, Readnum);
X alarm(0);
X if (Verbose > 5) {
X fprintf(stderr, "Read returned %d bytes\n", Lleft);
X }
X if (Lleft < 1)
X return TIMEOUT;
X --Lleft;
X if (Verbose > 8) {
X fprintf(stderr, "%02x ", *cdq&0377);
X }
X return (*cdq++ & Wcsmask);
X}
X#else
Xreadline(timeout)
Xint timeout;
X{
X int c;
X
X c = ReadSer(timeout);
X if(c<0)
X {
X switch(c) {
X
X case TIMEOUT:
X Lleft = 0;
X if (Verbose>1)
X fprintf(stderr, "Readline:TIMEOUT\n");
X return TIMEOUT;
X
X default:if(Verbose) fprintf(stderr,"readline: unknown error\n");
X return -1;break;
X }
X }
X else { if(Verbose>8) fprintf(stderr,"%02x ",c&0377);
X return(c&Wcsmask);
X }
X}
X
X#endif /* ifndef AMIGA */
X
X
X/*
X * Purge the modem input queue of all characters
X */
Xpurgeline()
X{
X Lleft = 0;
X#ifdef AMIGA
X PurgeSer();
X#else
X#ifdef USG
X ioctl(iofd, TCFLSH, 0);
X#else
X lseek(iofd, 0L, 2);
X#endif
X#endif /* AMIGA */
X}
X
X/*
X * Process incoming file information header
X */
Xprocheader(name)
Xchar *name;
X{
X register char *openmode, *p, **pp;
X
X /* set default parameters and overrides */
X openmode = "w";
X Thisbinary = (!Rxascii) || Rxbinary;
X if (Lzmanag)
X zmanag = Lzmanag;
X
X /*
X * Process ZMODEM remote file management requests
X */
X if (!Rxbinary && zconv == ZCNL) /* Remote ASCII override */
X Thisbinary = 0;
X if (zconv == ZCBIN) /* Remote Binary override */
X Thisbinary = TRUE;
X else if (zmanag == ZMAPND)
X openmode = "a";
X
X#ifndef BIX
X /* ZMPROT check for existing file */
X if (zmanag == ZMPROT && (fout=fopen(name, "r"))) {
X fclose(fout); return ERROR;
X }
X#endif
X
X Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
X
X p = name + 1 + strlen(name);
X if (*p) { /* file coming from Unix or DOS system */
X sscanf(p, "%ld%lo%o", &Bytesleft, &Modtime, &Filemode);
X#ifndef AMIGA /* if the user wants ascii conversion give it to him
X even if file is coming from UNIX */
X if (Filemode & UNIXFILE)
X ++Thisbinary;
X#endif
X if (Verbose) {
X#ifndef AMIGA
X fprintf(stderr, "Incoming: %s %ld %lo %o\n",
X name, Bytesleft, Modtime, Filemode);
X#else
X fprintf(stderr, "\nIncoming: %s length=%ld\n",
X name, Bytesleft); /* Trying to be a little less
X cryptic than the UNIX version*/
X#endif
X }
X }
X
X#ifdef BIX
X if ((fout=fopen("scratchpad", openmode)) == NULL)
X return ERROR;
X return OK;
X#else
X
X else { /* File coming from CP/M system */
X for (p=name; *p; ++p) /* change / to _ */
X if ( *p == '/')
X *p = '_';
X
X if ( *--p == '.') /* zap trailing period */
X *p = 0;
X }
X
X if (!Zmodem && MakeLCPathname && !IsAnyLower(name))
X uncaps(name);
X if (Topipe) {
X#ifndef AMIGA
X sprintf(Pathname, "%s %s", Progname+2, name);
X if (Verbose)
X fprintf(stderr, "Topipe: %s %s\n",
X Pathname, Thisbinary?"BIN":"ASCII");
X if ((fout=popen(Pathname, "w")) == NULL)
X return ERROR;
X#endif
X } else {
X strcpy(Pathname, name);
X#ifndef AMIGA
X if (Verbose) {
X fprintf(stderr, "Receiving %s %s %s\n",
X name, Thisbinary?"BIN":"ASCII", openmode);
X }
X checkpath(name);
X#else
X if (Verbose) {
X fprintf(stderr, "file transfer mode is %s, file open mode is %s\n",
X Thisbinary?"BIN":"ASCII", openmode);
X }
X#endif
X if (Nflag)
X name = "/dev/null";
X if ((fout=fopen(name, openmode)) == NULL)
X return ERROR;
X }
X return OK;
X#endif /* BIX */
X}
X
X/*
X * Putsec writes the n characters of buf to receive file fout.
X * If not in binary mode, carriage returns, and all characters
X * starting with CPMEOF are discarded.
X */
Xputsec(buf, n)
Xchar *buf;
Xregister n;
X{
X register char *p;
X
X if (Thisbinary) {
X for (p=buf; --n>=0; )
X if( putc( *p++, fout)==EOF )
X return ERROR;
X }
X else {
X if (Eofseen)
X return OK;
X for (p=buf; --n>=0; ++p ) {
X if ( *p == '\r')
X continue;
X if (*p == CPMEOF) {
X Eofseen=TRUE; return OK;
X }
X if( putc(*p ,fout)==EOF )
X return ERROR;
X }
X }
X return OK;
X}
X
X#ifndef AMIGA
X/*
X * Send a character to modem. Small is beautiful.
X */
Xsendline(c)
X{
X char d;
X
X d = c;
X if (Verbose>6)
X fprintf(stderr, "Sendline: %x\n", c);
X write(1, &d, 1);
X}
X#else
Xsendline(c)
Xint c;
X{
X char d;
X int retc;
X
X d=c;
X if(Verbose>6)
X fprintf(stderr,"S:%02x\n",c);
X if( (retc=LWriteSer(&d,1))!=0 )
X if(Verbose) fprintf(stderr,"sendline:Error sending character %d\n",retc);
X}
X#endif
X
Xxsendline(c)
X{
X sendline(c);
X}
X
Xflushmo() {}
X
X
X
X
X/* make string s lower case */
Xuncaps(s)
Xregister char *s;
X{
X for ( ; *s; ++s)
X if (isupper(*s))
X *s = tolower(*s);
X}
X/*
X * IsAnyLower returns TRUE if string s has lower case letters.
X */
XIsAnyLower(s)
Xregister char *s;
X{
X for ( ; *s; ++s)
X if (islower(*s))
X return TRUE;
X return FALSE;
X}
X
X/*
X * substr(string, token) searches for token in string s
X * returns pointer to token within string if found, NULL otherwise
X */
Xchar *
Xsubstr(s, t)
Xregister char *s,*t;
X{
X register char *ss,*tt;
X /* search for first char of token */
X for (ss=s; *s; s++)
X if (*s == *t)
X /* compare token with substring */
X for (ss=s,tt=t; ;) {
X if (*tt == 0)
X return s;
X if (*ss++ != *tt++)
X break;
X }
X return NULL;
X}
X
X/*
X * Log an error
X */
X/*VARARGS1*/
Xzperr(s,p,u)
Xchar *s, *p, *u;
X{
X if (Verbose <= 0)
X return;
X fprintf(stderr, "Retry %d: ", errors);
X fprintf(stderr, s, p, u);
X fprintf(stderr, "\n");
X}
X
X/* send cancel string to get the other end to shut up */
Xcanit()
X{
X static char canistr[] = {
X 24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
X };
X#ifndef AMIGA
X printf(canistr);
X#else
X LWriteSer(canistr,strlen(canistr));
X#endif
X Lleft=0; /* Do read next time ... */
X fflush(stdout);
X}
X
X#ifndef AMIGA
X/*
X * Return 1 iff stdout and stderr are different devices
X * indicating this program operating with a modem on a
X * different line
X */
Xfromcu()
X{
X struct stat a, b;
X fstat(1, &a); fstat(2, &b);
X return (a.st_rdev != b.st_rdev);
X}
X#else /* AMIGA */
Xfromcu()
X{
X return TRUE;
X}
X#endif
X
Xreport(sct)
Xint sct;
X{
X if (Verbose>1)
X fprintf(stderr,"%03d%c",sct,sct%10? ' ' : '\r');
X}
X
X/*
X * If called as [-][dir/../]vrzCOMMAND set Verbose to 1
X * If called as [-][dir/../]rzCOMMAND set the pipe flag
X * If called as rb use YMODEM protocol
X */
Xchkinvok(s)
Xchar *s;
X{
X register char *p;
X
X p = s;
X while (*p == '-')
X s = ++p;
X while (*p)
X if (*p++ == '/')
X s = p;
X if (*s == 'v') {
X Verbose=1; ++s;
X }
X Progname = s;
X if (s[0]=='r' && s[1]=='b')
X Nozmodem = TRUE;
X#ifndef AMIGA
X if (s[2] && s[0]=='r' && s[1]=='b')
X Topipe=TRUE;
X if (s[2] && s[0]=='r' && s[1]=='z')
X Topipe=TRUE;
X#endif
X}
X
X#ifndef AMIGA
X/*
X * Totalitarian Communist pathname processing
X */
Xcheckpath(name)
Xchar *name;
X{
X if (Restricted) {
X if (fopen(name, "r") != NULL) {
X canit();
X fprintf(stderr, "\r\nrz: %s exists\n", name);
X bibi(-1);
X }
X /* restrict pathnames to current tree or uucppublic */
X if ( substr(name, "../")
X || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
X canit();
X fprintf(stderr,"\r\nrz:\tSecurity Violation\r\n");
X bibi(-1);
X }
X }
X}
X#endif
X/*
X * Initialize for Zmodem receive attempt, try to activate Zmodem sender
X * Handles ZSINIT frame
X * Return ZFILE if Zmodem filename received, -1 on error,
X * ZCOMPL if transaction finished, else 0
X */
Xtryz()
X{
X register c, n;
X register cmdzack1flg;
X
X if (Nozmodem) /* Check for "rb" program name */
X return 0;
X
X
X for (n=Zmodem?15:5; --n>=0; ) {
X /* Set buffer length (0) and capability flags */
X stohdr(0L);
X#ifdef CANBREAK
X Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;
X#else
X Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;
X#endif
X if (Zctlesc)
X Txhdr[ZF0] |= TESCCTL;
X zshhdr(tryzhdrtype, Txhdr);
X if (tryzhdrtype == ZSKIP) /* Don't skip too far */
X tryzhdrtype = ZRINIT; /* CAF 8-21-87 */
Xagain:
X switch (zgethdr(Rxhdr, 0)) {
X case ZRQINIT:
X continue;
X case ZEOF:
X continue;
X case TIMEOUT:
X continue;
X case ZFILE:
X zconv = Rxhdr[ZF0];
X zmanag = Rxhdr[ZF1];
X ztrans = Rxhdr[ZF2];
X tryzhdrtype = ZRINIT;
X c = zrdata(secbuf, KSIZE);
X mode(3);
X if (c == GOTCRCW)
X return ZFILE;
X zshhdr(ZNAK, Txhdr);
X goto again;
X case ZSINIT:
X Zctlesc = TESCCTL & Rxhdr[ZF0];
X if (zrdata(Attn, ZATTNLEN) == GOTCRCW) {
X zshhdr(ZACK, Txhdr);
X goto again;
X }
X zshhdr(ZNAK, Txhdr);
X goto again;
X case ZFREECNT:
X stohdr(getfree());
X zshhdr(ZACK, Txhdr);
X goto again;
X case ZCOMMAND:
X cmdzack1flg = Rxhdr[ZF0];
X if (zrdata(secbuf, KSIZE) == GOTCRCW) {
X if (cmdzack1flg & ZCACK1)
X stohdr(0L);
X else
X stohdr((long)sys2(secbuf));
X purgeline(); /* dump impatient questions */
X do {
X zshhdr(ZCOMPL, Txhdr);
X }
X while (++errors<20 && zgethdr(Rxhdr,1) != ZFIN);
X ackbibi();
X if (cmdzack1flg & ZCACK1)
X exec2(secbuf);
X return ZCOMPL;
X }
X zshhdr(ZNAK, Txhdr); goto again;
X case ZCOMPL:
X goto again;
X default:
X continue;
X case ZFIN:
X ackbibi(); return ZCOMPL;
X case ZCAN:
X return ERROR;
X }
X }
X return 0;
X}
X
X/*
X * Receive 1 or more files with ZMODEM protocol
X */
Xrzfiles()
X{
X register c;
X
X for (;;) {
X switch (c = rzfile()) {
X case ZEOF:
X case ZSKIP:
X switch (tryz()) {
X case ZCOMPL:
X return OK;
X default:
X return ERROR;
X case ZFILE:
X break;
X }
X continue;
X default:
X return c;
X case ERROR:
X return ERROR;
X }
X }
X}
X
X/*
X * Receive a file with ZMODEM protocol
X * Assumes file name frame is in secbuf
X */
Xrzfile()
X{
X register c, n;
X long rxbytes;
X
X Eofseen=FALSE;
X if (procheader(secbuf) == ERROR) {
X return (tryzhdrtype = ZSKIP);
X }
X#ifdef AMIGA /* skip over file if it won't fit on disk */
X if (Skip && Bytesleft!=DEFBYTL && Bytesleft>getfree()) {
X fprintf(stderr,"rz:Not enough room left on disk for %s. (skipping it)\n",secbuf);
X return (tryzhdrtype = ZSKIP);
X }
X#endif
X n = 20; rxbytes = 0l;
X
X for (;;) {
X stohdr(rxbytes);
X zshhdr(ZRPOS, Txhdr);
Xnxthdr:
X switch (c = zgethdr(Rxhdr, 0)) {
X default:
X vfile("rzfile: zgethdr returned %d", c);
X return ERROR;
X case ZNAK:
X case TIMEOUT:
X if ( --n < 0) {
X vfile("rzfile: zgethdr returned %d", c);
X return ERROR;
X }
X case ZFILE:
X zrdata(secbuf, KSIZE);
X continue;
X case ZEOF:
X if (rclhdr(Rxhdr) != rxbytes) {
X /*
X * Ignore eof if it's at wrong place - force
X * a timeout because the eof might have gone
X * out before we sent our zrpos.
X */
X errors = 0; goto nxthdr;
X }
X if (closeit()) {
X tryzhdrtype = ZFERR;
X vfile("rzfile: closeit returned <> 0");
X return ERROR;
X }
X vfile("rzfile: normal EOF");
X return c;
X case ERROR: /* Too much garbage in header search error */
X if ( --n < 0) {
X vfile("rzfile: zgethdr returned %d", c);
X return ERROR;
X }
X zmputs(Attn);
X continue;
X case ZDATA:
X if (rclhdr(Rxhdr) != rxbytes) {
X if ( --n < 0) {
X return ERROR;
X }
X zmputs(Attn); continue;
X }
Xmoredata:
X if (Verbose>1)
X fprintf(stderr, "\r%7ld ZMODEM%s ",
X rxbytes, Crc32?" CRC-32":"");
X switch (c = zrdata(secbuf, KSIZE)) {
X case ZCAN:
X vfile("rzfile: zgethdr returned %d", c);
X return ERROR;
X case ERROR: /* CRC error */
X if ( --n < 0) {
X vfile("rzfile: zgethdr returned %d", c);
X return ERROR;
X }
X zmputs(Attn);
X continue;
X case TIMEOUT:
X if ( --n < 0) {
X vfile("rzfile: zgethdr returned %d", c);
X return ERROR;
X }
X continue;
X case GOTCRCW:
X n = 20;
X putsec(secbuf, Rxcount);
X rxbytes += Rxcount;
X stohdr(rxbytes);
X zshhdr(ZACK, Txhdr);
X sendline(XON);
X goto nxthdr;
X case GOTCRCQ:
X n = 20;
X putsec(secbuf, Rxcount);
X rxbytes += Rxcount;
X stohdr(rxbytes);
X zshhdr(ZACK, Txhdr);
X goto moredata;
X case GOTCRCG:
X n = 20;
X putsec(secbuf, Rxcount);
X rxbytes += Rxcount;
X goto moredata;
X case GOTCRCE:
X n = 20;
X putsec(secbuf, Rxcount);
X rxbytes += Rxcount;
X goto nxthdr;
X }
X }
X }
X}
X
X/*
X * Send a string to the modem, processing for \336 (sleep 1 sec)
X * and \335 (break signal)
X */
Xzmputs(s)
Xchar *s;
X{
X register c;
X
X while (*s) {
X switch (c = *s++) {
X case '\336':
X sleep(1); continue;
X case '\335':
X sendbrk(); continue;
X default:
X sendline(c);
X }
X }
X}
X
X/*
X * Close the receive dataset, return OK or ERROR
X */
Xcloseit()
X{
X#ifdef AMIGA
X long attr;
X int res;
X struct DateStamp dss;
X long time;
X#else
X if (Topipe) {
X if (pclose(fout)) {
X return ERROR;
X }
X return OK;
X }
X#endif
X if (fclose(fout)==ERROR) {
X fprintf(stderr, "file close ERROR\n");
X return ERROR;
X }
X#ifndef AMIGA
X if (Modtime) {
X timep[0] = time(NULL);
X timep[1] = Modtime;
X utime(Pathname, timep);
X }
X if (Filemode)
X chmod(Pathname, (07777 & Filemode));
X#else
X if (Modtime && gmt_diff_set) {
X time=Modtime-(2*366+6*365)*24*60*60 +(gmt_diff * 60 * 60);
X dss.ds_Tick=(time%60)*TICKS_PER_SECOND;
X time/=60;
X dss.ds_Minute=time%(60*24);
X time/=60;
X dss.ds_Days=time/24;
X file_date(&dss,Pathname);
X }
X if (SetProtect && Filemode) {
X /* Turn off flag to allow the action. */
X#ifndef FIBF_SCRIPT
X#define FIBF_SCRIPT (1 << 6)
X#endif
X#ifndef FIBF_PURE
X#define FIBF_PURE (1 << 5)
X#endif
X#ifndef FIBF_HIDDEN
X#define FIBF_HIDDEN (1 << 7)
X#endif
X attr = 0L;
X if(!(Filemode & 0400)) attr |= FIBF_READ;
X if(!(Filemode & 0200)) attr |= (FIBF_WRITE | FIBF_DELETE);
X if(!(Filemode & 0100)) attr |= FIBF_EXECUTE;
X res=SetProtection(Pathname, attr);
X }
X#endif
X return OK;
X}
X
X/*
X * Ack a ZFIN packet, let byegones be byegones
X */
Xackbibi()
X{
X register n;
X
X vfile("ackbibi:");
X Readnum = 1;
X stohdr(0L);
X for (n=3; --n>=0; ) {
X purgeline();
X zshhdr(ZFIN, Txhdr);
X switch (readline(100)) {
X case 'O':
X readline(1); /* Discard 2nd 'O' */
X vfile("ackbibi complete");
X return;
X case RCDO:
X return;
X case TIMEOUT:
X default:
X break;
X }
X }
X}
X
X
X
X/*
X * Local console output simulation
X */
Xbttyout(c)
X{
X#ifndef AMIGA
X if (Verbose || fromcu())
X#else
X if (Verbose>2)
X#endif
X putc(c, stderr);
X}
X
X#ifndef AMIGA
X/*
X * Strip leading ! if present, do shell escape.
X */
Xsys2(s)
Xregister char *s;
X{
X if (*s == '!')
X ++s;
X return system(s);
X}
X/*
X * Strip leading ! if present, do exec.
X */
Xexec2(s)
Xregister char *s;
X{
X if (*s == '!')
X ++s;
X mode(0);
X execl("/bin/sh", "sh", "-c", s);
X}
X#else
Xsys2(s)
Xchar *s;
X{
X if (*s == '!')
X ++s;
X /* if it's just an "echo" fake it */
X if(strncmp(s,"echo",4)==0) { printf("%s\n",s+5);return 0; }
X else return(!Execute(s,0L,0L));
X}
X
X
Xexec2(s)
Xchar *s;
X{
X char cmdbuf[256]; /* Anybody like nice long commands? */
X
X if (*s == '!')
X ++s;
X sprintf(cmdbuf,"run %s",s);
X Execute(cmdbuf,0L,0L);
X}
X#endif
X/* End of rz.c */
SHAR_EOF
echo "End of archive 4 (of 9)"
# if you want to concatenate archives, remove anything after this line
exit